package avicit.bdp.dms.prm.service;

import avicit.bdp.common.dto.BdpPrmEngineResourceDTO;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.common.utils.redis.RedisCacheHelper;
import avicit.bdp.core.constant.Constants;
import avicit.bdp.core.util.json.JSONUtils;
import avicit.bdp.dms.prm.dao.BdpPrmEngineResourceDao;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.commons.utils.PojoUtil;
import avicit.platform6.core.context.ThreadContextHelper;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.properties.PlatformConstant;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.github.pagehelper.Page;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间： 2021-04-26 14:43
 * @类说明：引擎资源表Service
 * @修改记录：
 */
@Service
public class BdpPrmEngineResourceService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BdpPrmEngineResourceService.class);

    private static String ENGINE_RESOURCE_REDIS = "bdp:dds:engineresource:";

    @Autowired
    private BdpPrmEngineResourceDao bdpPrmEngineResourceDao;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RedisCacheHelper redisCacheHelper;

    /**
     * 按条件分页查询
     *
     * @param type         类型：0--计算引擎；1--存储引擎
     * @param resourceType 资源或引擎类型 0-Flink 1-Spark 2-hdfs 3-oss
     * @param keyWords     关键词
     * @param pageNo       当前页
     * @param pageSize     分页大小
     * @return 分页列表
     */
    @Transactional(readOnly = true)
    public QueryRespBean<BdpPrmEngineResourceDTO> searchBdpPrmEngineResourceByPage(Integer type,
                                                                                   Integer resourceType,
                                                                                   String keyWords,
                                                                                   Integer pageNo,
                                                                                   Integer pageSize,
                                                                                   String secretLevel) {

        QueryRespBean<BdpPrmEngineResourceDTO> queryRespBean = new QueryRespBean<>();
        try {
            List<String> wordSecretList = new ArrayList<>();
            if(StringUtils.isNotEmpty(secretLevel)){
                wordSecretList.add(secretLevel);
            }else{
                wordSecretList = ThreadContextHelper.getWordSecretList();
            }
            com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);
            Page<BdpPrmEngineResourceDTO> dataList = bdpPrmEngineResourceDao.searchBdpPrmEngineResourceByPage(type, resourceType, keyWords, wordSecretList);
            queryRespBean.setResult(dataList);
            BdpLogUtil.log4Query(queryRespBean);
            return queryRespBean;
        } catch (Exception e) {
            LOGGER.error("searchBdpPrmEngineResourceByPage error: ", e);
            throw new BusinessException(e.getMessage(), e);
        }
    }


    /**
     * 通过主键查询单条记录
     *
     * @param id 主键id
     * @return BdpPrmEngineResourceDTO
     */
    @Transactional(readOnly = true)
    public BdpPrmEngineResourceDTO queryBdpPrmEngineResourceByPrimaryKey(String id) {
        try {
            BdpPrmEngineResourceDTO bdpPrmEngineResourceDTO = bdpPrmEngineResourceDao.selectByPrimaryKey(id);
            BdpLogUtil.log4Query(bdpPrmEngineResourceDTO);
            return bdpPrmEngineResourceDTO;
        } catch (Exception e) {
            LOGGER.error("queryBdpPrmEngineResourceByPrimaryKey error: ", e);
            throw new BusinessException(e.getMessage(), e);
        }
    }

    /**
     * 新增对象
     *
     * @param bdpPrmEngineResourceDTO 保存对象
     * @return String
     */
    @Transactional(rollbackFor = Exception.class)
    public String insertBdpPrmEngineResource(BdpPrmEngineResourceDTO bdpPrmEngineResourceDTO) {
        try {
            bdpPrmEngineResourceDTO.setId(ComUtil.getId());
            PojoUtil.setSysProperties(bdpPrmEngineResourceDTO, PlatformConstant.OpType.insert);

            bdpPrmEngineResourceDao.insertBdpPrmEngineResource(bdpPrmEngineResourceDTO);

            //存儲引擎存入redis緩存
            if (BdpPrmEngineResourceDTO.TYPE_STORAGE.equals(bdpPrmEngineResourceDTO.getType())) {
                insertRedisCach(bdpPrmEngineResourceDTO);
            }

            //记录日志
            BdpLogUtil.log4Insert(bdpPrmEngineResourceDTO);
            return bdpPrmEngineResourceDTO.getId();
        } catch (Exception e) {
            LOGGER.error("insertBdpPrmEngineResource error: ", e);
            throw new BusinessException(e.getMessage(), e);
        }
    }

    /**
     * 添加到redis緩存
     *
     * @param bdpPrmEngineResourceDTO
     */
    private void insertRedisCach(BdpPrmEngineResourceDTO bdpPrmEngineResourceDTO) {
        try {
            redisCacheHelper.set(ENGINE_RESOURCE_REDIS + bdpPrmEngineResourceDTO.getId(),
                    JSONUtils.toJsonString(bdpPrmEngineResourceDTO.getStorageResourceConf()));
            if (BdpPrmEngineResourceDTO.SYSTEM_DEFAULT.equals(bdpPrmEngineResourceDTO.getSystemDefault())) {
                redisCacheHelper.set(Constants.REDIS_KEY_SYSTEM_DEFAULT_STORAGE_ENGINE, JSONUtils.toJsonString(bdpPrmEngineResourceDTO.getStorageResourceConf()));
                // 将其他的默认存储引擎全部置位非默认
                bdpPrmEngineResourceDao.updateSystemDefaultState(bdpPrmEngineResourceDTO.getType(), 0);
            }
        } catch (Exception e) {
            LOGGER.error("insertRedisCach error: ", e);
        }
    }

    /**
     * 修改对象全部字段
     *
     * @param bdpPrmEngineResourceDTO 修改对象
     * @return int
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateBdpPrmEngineResource(BdpPrmEngineResourceDTO bdpPrmEngineResourceDTO) {
        try {
            if (BdpPrmEngineResourceDTO.TYPE_STORAGE.equals(bdpPrmEngineResourceDTO.getType())) {
                insertRedisCach(bdpPrmEngineResourceDTO);
            }
            int ret = bdpPrmEngineResourceDao.updateBdpPrmEngineResourceAll(getUpdateDto(bdpPrmEngineResourceDTO));
            if (ret == 0) {
                throw new BusinessException("数据失效，请重新更新");
            }
            return ret;
        } catch (Exception e) {
            LOGGER.error("updateBdpPrmEngineResource error: ", e);
            throw new BusinessException(e.getMessage(), e);
        }
    }


    /**
     * 内部方法，获取修改的dto对象
     */
    private BdpPrmEngineResourceDTO getUpdateDto(BdpPrmEngineResourceDTO bdpPrmEngineResourceDTO) {
        BdpPrmEngineResourceDTO oldDTO = findById(bdpPrmEngineResourceDTO.getId());
        if (oldDTO == null) {
            throw new BusinessException("数据不存在");
        }
        //记录日志
        BdpLogUtil.log4Update(bdpPrmEngineResourceDTO, oldDTO);
        PojoUtil.setSysProperties(bdpPrmEngineResourceDTO, PlatformConstant.OpType.update);
        PojoUtil.copyProperties(oldDTO, bdpPrmEngineResourceDTO, true);
        return oldDTO;
    }


    /**
     * 按主键单条删除
     *
     * @param id 主键id
     * @return int
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteBdpPrmEngineResourceById(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new BusinessException("删除失败！传入的参数主键为null");
        }
        try {

            int useNum = bdpPrmEngineResourceDao.selectResourceUseState(id);
            if (useNum > 0) {
                throw new BusinessException("资源在使用中,不能删除！");
            }

            //记录日志
            BdpPrmEngineResourceDTO bdpPrmEngineResourceDTO = findById(id);
            if (bdpPrmEngineResourceDTO == null) {
                throw new BusinessException("删除失败！对象不存在");
            }
            // 发送通知，告知redis订阅者，处理连接缓存
            if (BdpPrmEngineResourceDTO.TYPE_STORAGE.equals(bdpPrmEngineResourceDTO.getType())) {
                //redisTemplate.convertAndSend(Constants.REDIS_TOPIC_STORAGE_CACHE,
                //        JSONUtils.toJsonString(bdpPrmEngineResourceDTO.getStorageResourceConf()));
                redisCacheHelper.del(id);
            }
            BdpLogUtil.log4Delete(bdpPrmEngineResourceDTO);
            //删除业务数据
            return bdpPrmEngineResourceDao.deleteBdpPrmEngineResourceById(id);
        } catch (Exception e) {
            LOGGER.error("deleteBdpPrmEngineResourceById error: ", e);
            throw new BusinessException(e.getMessage(), e);
        }
    }

    /**
     * 批量删除数据
     *
     * @param ids id的数组
     * @return int
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteBdpPrmEngineResourceByIds(List<String> ids) {
        int result = 0;
        for (String id : ids) {
            BdpPrmEngineResourceDTO bdpPrmEngineResourceDTO = bdpPrmEngineResourceDao.selectByPrimaryKey(id);
            BdpLogUtil.log4Delete(bdpPrmEngineResourceDTO);
            deleteBdpPrmEngineResourceById(id);
            result++;
        }
        return result;
    }

    /**
     * 日志专用，内部方法，不再记录日志
     *
     * @param id 主键id
     * @return BdpPrmEngineResourceDTO
     */
    private BdpPrmEngineResourceDTO findById(String id) {
        return bdpPrmEngineResourceDao.selectByPrimaryKey(id);
    }

    public void defaultResource(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new BusinessException("传入的参数主键为null");
        }
        try {
            BdpPrmEngineResourceDTO bdpPrmEngineResourceDTO = this.findById(id);
            //更新为非默认
            bdpPrmEngineResourceDao.updateSystemDefaultState(bdpPrmEngineResourceDTO.getType(), 0);
            //更新默认
            bdpPrmEngineResourceDao.updateSystemDefaultById(id);

            String logTitle = "设置默认引擎：【" + bdpPrmEngineResourceDTO.getName() + "】";
            BdpLogUtil.log("计算引擎管理模块", logTitle, PlatformConstant.OpType.insert);
        } catch (Exception e) {
            LOGGER.error("default Resource error: ", e);
            throw new BusinessException(e.getMessage(), e);
        }
    }

    public BdpPrmEngineResourceDTO findDefaultEngineResource(int type) {
        return this.bdpPrmEngineResourceDao.findDefaultEngineResource(type);
    }
}
